'
' DotNetNuke -  http://www.dotnetnuke.com
' Copyright (c) 2002-2005
' by Shaun Walker ( sales@perpetualmotion.ca ) of Perpetual Motion Interactive Systems Inc. ( http://www.perpetualmotion.ca )
'
' Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
' documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
' the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
' to permit persons to whom the Software is furnished to do so, subject to the following conditions:
'
' The above copyright notice and this permission notice shall be included in all copies or substantial portions 
' of the Software.
'
' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
' DEALINGS IN THE SOFTWARE.
'
Imports DotNetNuke
Imports System.IO
Imports ICSharpCode.SharpZipLib.Zip
Imports System.Web.UI.WebControls
Imports System.Web.UI.HtmlControls

Namespace DotNetNuke.Modules.ProjectTracker

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' The EditPT_Projects PortalModuleBase is used to manage PT_Projects
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public MustInherit Class ProjectTrackerEdit
        Inherits Entities.Modules.PortalModuleBase

#Region "Controls"

        Protected WithEvents fldProjectName As TextBox  ' nvarchar
        Protected WithEvents fldVersion As TextBox  ' nvarchar
        ' int
        ' int
        Protected WithEvents fldDescription As TextBox  ' ntext
        Protected WithEvents inpFile As HtmlInputFile
        Protected WithEvents lblFileInfo As Label
        Protected WithEvents lblFileError As Label
        Protected WithEvents rfvProjectName As RequiredFieldValidator
        Protected WithEvents rfvVersion As RequiredFieldValidator
        Protected WithEvents rfvDescription As RequiredFieldValidator
        Protected WithEvents ddlProjectLead As DropDownList
        Protected WithEvents fldProjectLead As TextBox

        'tasks
        Protected WithEvents cmdUpdate As LinkButton
        Protected WithEvents cmdCancel As LinkButton
        Protected WithEvents cmdDelete As LinkButton

        ' footer
        Protected WithEvents ctlAudit As UI.UserControls.ModuleAuditControl

#End Region

#Region "Private Members"

        Private m_itemId As Integer = -1
        Private m_moduleId As Integer = -1
        Private m_ProjectsController As New DotNetNuke.Modules.ProjectTracker.ProjectsController
        Private m_ProjectsInfo As DotNetNuke.Modules.ProjectTracker.ProjectsInfo

#End Region

#Region "Event Handlers"

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Page_Load runs when the control is loaded
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Try
                ' Determine ItemId of PT_Projects to Update
                If Not Request.QueryString("ItemId") Is Nothing Then
                    m_itemId = Int32.Parse(Request.QueryString("ItemId"))
                End If

                ' /// Determine ModuleId
                m_moduleId = Int32.Parse(Request.Params("Mid"))

                ' If the page is being requested the first time, determine if an
                ' PT_Projects itemId value is specified, and if so populate page
                ' contents with the PT_Projects details
                If Page.IsPostBack = False Then

                    cmdDelete.Attributes.Add("onClick", "javascript:return confirm('" & Localization.GetString("DeleteItem") & "');")

                    If m_itemId <> -1 Then
                        ' Obtain a single row of PT_Projects information
                        ' /// Retrieve the requested Item using the ItemId
                        m_ProjectsInfo = m_ProjectsController.GetProjectsInfo(m_itemId)

                        If Not m_ProjectsInfo Is Nothing Then
                            fldProjectName.Text = m_ProjectsInfo.ProjectName.ToString()
                            fldVersion.Text = m_ProjectsInfo.Version.ToString()
                            fldProjectLead.Text = UserInfo.DisplayName
                            ' fldProjectChair.Text = m_ProjectsInfo.ProjectChair.ToString()
                            fldDescription.Text = m_ProjectsInfo.Description.ToString()
                            lblFileInfo.Text = m_ProjectsInfo.Url.ToString() & " -- uploaded " & m_ProjectsInfo.CreatedDate.ToString
                            ctlAudit.CreatedDate = m_ProjectsInfo.CreatedDate.ToString
                            ctlAudit.CreatedByUser = m_ProjectsInfo.CreatedByUser.ToString

                        Else       ' security violation attempt to access item not related to this Module

                            Response.Redirect(NavigateURL(), True)
                        End If
                    Else
                        fldProjectLead.Text = UserInfo.DisplayName
                        cmdDelete.Visible = False
                        ctlAudit.Visible = False
                    End If

                    fldProjectLead.Enabled = False

                End If

            Catch exc As Exception    'Module failed to load
                ProcessModuleLoadException(Me, exc)
            End Try
        End Sub

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' cmdCancel_Click runs when the cancel button is clicked
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Private Sub cmdCancel_Click(ByVal sender As Object, ByVal e As EventArgs) Handles cmdCancel.Click
            Try
                Response.Redirect(NavigateURL(), True)
            Catch exc As Exception    'Module failed to load
                ProcessModuleLoadException(Me, exc)
            End Try
        End Sub

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' cmdDelete_Click runs when the delete button is clicked
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Private Sub cmdDelete_Click(ByVal sender As Object, ByVal e As EventArgs) Handles cmdDelete.Click
            Try
                If m_itemId <> -1 Then
                    m_ProjectsController.DeleteProjects(m_itemId)
                End If

                ' Redirect back to the portal home page
                Response.Redirect(NavigateURL(), True)
            Catch exc As Exception    'Module failed to load
                ProcessModuleLoadException(Me, exc)
            End Try
        End Sub

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' cmdUpdate_Click runs when the update button is clicked
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Private Sub cmdUpdate_Click(ByVal sender As Object, ByVal e As EventArgs) Handles cmdUpdate.Click
            Dim strFileName As String = ""
            Dim strPath As String = ""
            Dim bIsFile As Boolean
            Dim historyController As New historyController
            Dim historyInfo As New historyInfo

            Try
                ' Only Update if Entered data is Valid
                If Page.IsValid = True Then

                    If Not Directory.Exists(context.Server.MapPath("~/Portals/" & PortalSettings.PortalId & "/Projects")) Then
                        Directory.CreateDirectory(context.Server.MapPath("~/Portals/" & PortalSettings.PortalId & "/Projects"))
                    End If

                    ' make sure the uploaded file is named properly
                    ' it must end in _release.zip
                    lblFileError.Text = ""

                    If m_itemId = -1 Then
                        ' uploading a new item, a file is required, validate the package to make sure it is
                        ' named properly and contains the proper contents
                        If inpFile.PostedFile.FileName = "" Then
                            lblFileError.Text = "** ERROR ** A release package is required."
                        Else
                            bIsFile = True
                        End If
                    Else
                        ' editing an exisitng item, so file is optional, however if it's included, validate it 
                        If inpFile.PostedFile.FileName = "" Then
                            bIsFile = False
                        Else
                            bIsFile = True
                        End If
                    End If

                    If fldVersion.Text.Trim().Length <> 8 Then
                        lblFileError.Text = "** ERROR ** Module Version must be in 00.00.00 format."
                    Else
                        If fldVersion.Text.Substring(2, 1) <> "." Then
                            lblFileError.Text = "** ERROR ** Module Version must be in 00.00.00 format."
                        Else
                            If fldVersion.Text.Substring(5, 1) <> "." Then
                                lblFileError.Text = "** ERROR ** Module Version must be in 00.00.00 format."
                            End If
                        End If
                    End If

                    If lblFileError.Text = "" And bIsFile Then
                        strPath = context.Server.MapPath("~/Portals/" & PortalSettings.PortalId & "/Projects") & "/"
                        strFileName = strPath & Path.GetFileName(inpFile.PostedFile.FileName)
                        If Not strFileName.ToLower.EndsWith("_package.zip") Then
                            lblFileError.Text = "** ERROR ** Filename is not in correct format. Format should be 'module_version_package.zip'"
                        Else
                            ' upload the file so we can unzip it and validate the contents
                            If File.Exists(strFileName) Then
                                File.SetAttributes(strFileName, FileAttributes.Normal)
                                File.Delete(strFileName)
                            End If
                            inpFile.PostedFile.SaveAs(strFileName)

                            ' make sure the uploaded package contains the proper components
                            ' -- module_version_install.zip
                            ' -- module_version_source.zip
                            ' -- module_version_testcases.txt
                            ' -- module_version_releasenotes.txt
                            Dim objZipEntry As ZipEntry
                            Dim objZipInputStream As ZipInputStream
                            Try
                                objZipInputStream = New ZipInputStream(File.OpenRead(strFileName))
                            Catch ex As Exception
                                lblFileError.Text = ex.Message
                                File.SetAttributes(strFileName, FileAttributes.Normal)
                                File.Delete(strFileName)
                            End Try

                            If lblFileError.Text = "" Then
                                objZipEntry = objZipInputStream.GetNextEntry
                                Dim iTemp As Long

                                Dim iEntries As Integer = 0
                                While Not objZipEntry Is Nothing
                                    If objZipEntry.Name.ToLower.EndsWith("_install.zip") Then
                                        iEntries += 1
                                    End If
                                    If objZipEntry.Name.ToLower.EndsWith("_source.zip") Then
                                        iEntries += 1
                                    End If
                                    If objZipEntry.Name.ToLower.EndsWith("_testcases.txt") Then
                                        iEntries += 1
                                    End If
                                    If objZipEntry.Name.ToLower.EndsWith("_releasenotes.txt") Then
                                        iEntries += 1
                                    End If
                                    objZipEntry = objZipInputStream.GetNextEntry
                                End While
                                objZipInputStream.Close()
                                If iEntries <> 4 Then
                                    lblFileError.Text = "** ERROR ** Package is missing one or more required files."
                                    File.SetAttributes(strFileName, FileAttributes.Normal)
                                    File.Delete(strFileName)
                                End If
                            End If
                        End If
                    End If

                    If lblFileError.Text = "" Then

                        ' we're good to go
                        Dim stateController As New StatesController
                        Dim states As ArrayList = stateController.GetStatesList(ModuleId)

                        ''' get the initial state for this workflow
                        Dim stateInfo As StatesInfo = CType(states(0), StatesInfo)

                        ''' save the project info
                        If m_itemId = -1 Then
                            m_ProjectsInfo = New ProjectsInfo
                            m_ProjectsInfo.CreatedByUser = UserInfo.UserID
                            m_ProjectsInfo.CurrentState = stateInfo.ItemID
                            m_ProjectsInfo.Status = "OPEN"
                            m_ProjectsInfo.ProjectLead = UserInfo.UserID
                            m_ProjectsInfo.ProjectChair = UserInfo.UserID
                        Else
                            m_ProjectsInfo = m_ProjectsController.GetProjectsInfo(m_itemId)
                        End If

                        m_ProjectsInfo.ItemID = m_itemId
                        m_ProjectsInfo.ModuleID = m_moduleId
                        m_ProjectsInfo.CreatedDate = Date.Now()
                        m_ProjectsInfo.ProjectName = fldProjectName.Text.Trim()
                        m_ProjectsInfo.Version = fldVersion.Text.Trim()
                        m_ProjectsInfo.Description = fldDescription.Text.Trim()
                        m_ProjectsInfo.Url = Path.GetFileName(inpFile.PostedFile.FileName)

                        If m_itemId = -1 Then
                            Dim newProjectID As Integer = m_ProjectsController.AddProjects(m_ProjectsInfo)
                            ''' add history records
                            historyInfo = New historyInfo
                            historyInfo.ProjectID = newProjectID
                            historyInfo.ModuleID = ModuleId
                            historyInfo.CreatedByUser = UserInfo.UserID
                            historyInfo.CreatedDate = Date.Now()
                            historyInfo.Activity = String.Format("PROJECT : {0} Version {1} SUBMITTED", m_ProjectsInfo.ProjectName, m_ProjectsInfo.Version)
                            historyInfo.ActivityType = "SUBMITTED"
                            historyInfo.ObjectID = -1
                            historyController.AddHistory(historyInfo)

                            '' mark each of the exit criteria for the initial state complete
                            Dim ecController As New ExitCriteriaController
                            For Each ecInfo As ExitCriteriaInfo In ecController.GetExitCriteriaList(stateInfo.ItemID)
                                historyInfo = Nothing
                                historyInfo = historyController.GetHistoryActivityByType(newProjectID, "EXITCRITERIA", ecInfo.ItemID)
                                If historyInfo Is Nothing Then
                                    historyInfo = New historyInfo
                                    historyInfo.ProjectID = newProjectID
                                    historyInfo.ModuleID = ModuleId
                                    historyInfo.CreatedByUser = UserInfo.UserID
                                    historyInfo.CreatedDate = Date.Now()
                                    historyInfo.Activity = String.Format("EXIT CRITERIA PASSED : {0}", ecInfo.Criteria)
                                    historyInfo.ActivityType = "EXITCRITERIA"
                                    historyInfo.ObjectID = ecInfo.ItemID
                                    historyController.AddHistory(historyInfo)
                                End If
                            Next

                            historyInfo.Activity = "New Project Submitted"
                            historyInfo.CreatedByUser = UserInfo.UserID
                            historyInfo.CreatedDate = Date.Now()
                            historyInfo.ModuleID = ModuleId
                            historyInfo.ProjectID = newProjectID
                            historyController.AddHistory(historyInfo)

                            ''' mark the initial state complete
                            historyInfo = New historyInfo
                            historyInfo.Activity = "STATE COMPLETE : " & stateInfo.StateName
                            historyInfo.CreatedByUser = UserInfo.UserID
                            historyInfo.CreatedDate = Date.Now()
                            historyInfo.ModuleID = ModuleId
                            historyInfo.ProjectID = newProjectID
                            historyController.AddHistory(historyInfo)

                            ''' point to the new project
                            m_ProjectsInfo = m_ProjectsController.GetProjectsInfo(newProjectID)

                            ''' send out state entry emails to subscribers and authorized roles
                            Dim mailer As New DotNetNuke.Modules.ProjectTracker.EMailer
                            Dim emails As New ArrayList
                            mailer.StateNotification("AUTH", m_ProjectsInfo, stateInfo, "PASS", emails)
                            mailer.StateNotification("SUBS", m_ProjectsInfo, stateInfo, "PASS", emails)
                            mailer.StateNotification("OWNER", m_ProjectsInfo, stateInfo, "PASS", emails)
                            emails = Nothing

                            ''' we've completed the first state, so advance the project
                            ''' to the next state
                            ''' get the initial state for this workflow
                            If states.Count > 1 Then
                                stateInfo = CType(states(1), StatesInfo)
                                m_ProjectsInfo.CurrentState = stateInfo.ItemID
                                m_ProjectsController.UpdateProjects(m_ProjectsInfo)
                                ''' send out email for new state
                                emails = New ArrayList
                                mailer.StateNotification("AUTH", m_ProjectsInfo, stateInfo, "ENTRY", emails)
                                mailer.StateNotification("SUBS", m_ProjectsInfo, stateInfo, "ENTRY", emails)
                                mailer.StateNotification("OWNER", m_ProjectsInfo, stateInfo, "ENTRY", emails)
                                emails = Nothing
                                ' write history record for entering new state
                                historyInfo = New historyInfo
                                historyInfo.ProjectID = m_ProjectsInfo.ItemID
                                historyInfo.ModuleID = ModuleId
                                historyInfo.CreatedByUser = UserInfo.UserID
                                historyInfo.CreatedDate = Date.Now()
                                historyInfo.Activity = String.Format("STATE ENTERED : {0}", stateInfo.StateName)
                                historyInfo.ActivityType = "STATEENTERED"
                                historyInfo.ObjectID = stateInfo.ItemID
                                historyController.AddHistory(historyInfo)
                            End If

                        Else
                            m_ProjectsController.UpdateProjects(m_ProjectsInfo)
                            ''' add history records
                            historyInfo = New historyInfo
                            historyInfo.ProjectID = m_ProjectsInfo.ItemID
                            historyInfo.ModuleID = ModuleId
                            historyInfo.CreatedByUser = UserInfo.UserID
                            historyInfo.CreatedDate = Date.Now()
                            historyInfo.Activity = String.Format("PROJECT EDITED by : {0}", UserInfo.Profile.FullName)
                            historyInfo.ActivityType = "EDITED"
                            historyInfo.ObjectID = -1
                            historyController.AddHistory(historyInfo)

                        End If


                        ' Redirect back to the portal home page
                        Response.Redirect(NavigateURL(), True)

                    End If

                End If
            Catch exc As Exception    'Module failed to load
                ProcessModuleLoadException(Me, exc)
            End Try
        End Sub

#End Region

#Region " Web Form Designer Generated Code "

        'This call is required by the Web Form Designer.
        <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

        End Sub

        Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
            'CODEGEN: This method call is required by the Web Form Designer
            'Do not modify it using the code editor.
            InitializeComponent()
        End Sub

#End Region

    End Class

End Namespace
